#coding:utf-8

"""
    XML and YAML data parser.
    result data must be:
        {'func1': [{'arg1':obj1, 'arg2':obj2}, {'arg1':obj3, 'arg2':obj4}]
        ,'func2': [{'arg':obj}]
        ,'func3': [{'arg1':obj1, 'arg2':obj2}, {'arg1':obj3, 'arg2':obj4}]
        }
        
    For XML format is(this root tag name must be 'test'):
        <test>
            <func1>
                <data>
                    <arg1> obj1 </arg1>
                    <arg2> obj2 </arg2>
                </data>
                <data>
                    <arg1> obj3 </arg1>
                    <arg2> obj4 </arg2>
                </data>
            </fun1>
        </test>
        
    For YAML format is:
        func1:
            -
            arg1: obj1
            arg2: obj2
            -
            arg1: obj3
            arg2: obj4
        func2:
            -
            arg1: obj1
            arg2: obj2
    this list token '-' can not be omitted if you need set more than one
    set of data.
"""

import os
import error

    


import xml.dom.minidom as xmldom

XML_DOM_ROOT = 'test'
XML_DOM_DATA_TAG = 'data'

def parse_xml_data(path):
    try:
        dom = xmldom.parse(path)
    except:
        raise error.ParserError("Xml parser error: %s[%s]"%(path, error.last_error_message()))
    
    root_name = dom.firstChild.tagName
    if root_name != XML_DOM_ROOT:
        raise ValueError("Root tag should be %s not %s"%(XML_DOM_ROOT, root_name))
    
    result = {}
    for data_node in dom.getElementsByTagName(XML_DOM_DATA_TAG):
        
        # find entire path
        node_names = []
        node = data_node.parentNode
        while node.nodeType == node.ELEMENT_NODE and node.tagName != XML_DOM_ROOT:
            node_names.append(node.tagName)     
            node = node.parentNode
        node_names.reverse()
        entire_path = str('.'.join(node_names))
        
        # find data
        data = {}
        for node in data_node.childNodes:
            if node.nodeType == node.ELEMENT_NODE:
                string = node.childNodes[0].data.strip()
                try:
                    obj = eval(string)
                except:
                    obj = string
                data[str(node.tagName)] = obj
                
        if not result.has_key(entire_path):
            result[entire_path] = []
        result[entire_path].append(data)
        
    return result

def parse_data(paths):
    for path in paths:
        ext = os.path.splitext(path)[1]
        if ext == '.xml':
            parse_call = parse_xml_data
        elif ext == '.yaml':
            parse_call = parse_yaml_data
        else:
            continue
        return parse_call(path)
    #raise NameError, "data path must be xml or yaml suffix:%s"%path

